package com.jd.jobkeeper.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Mono;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;

public class InvokerHandler {

    private static final Logger log = LoggerFactory.getLogger(InvokerHandler.class);

    private Method method;
    private Class<?> parameterType[];
    private Class<?> returnType;
    private Object proxy;

    public InvokerHandler(Object proxy, Method method) {
        try {
            this.method = method;
            this.proxy = proxy;
            this.parameterType = method.getParameterTypes();
            this.returnType = (Class) (((ParameterizedType) method.getGenericReturnType()).getActualTypeArguments()[0]);
        } catch (Exception e) {

        }


        //parameterType = types[0];

    }

    public <T> Mono<T> invoke(Object... args) {
        try {
            if (parameterType.length == 1) {
                return ((Mono) method.invoke(proxy, args[0])).cast(returnType);
            } else {
                return ((Mono) method.invoke(proxy, args)).cast(returnType);
            }
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            log.info("invoke.fail ", e);
            throw new RuntimeException(e);
        }
    }

    public Method getMethod() {
        return method;
    }

    public Class<?>[] getParameterType() {
        return parameterType;
    }

    public Class<?> getReturnType() {
        return returnType;
    }

    public Object getProxy() {
        return proxy;
    }
}
